package com.wx.spider.mobile.service.impl;

import com.wx.spider.common.enums.MqMsgBean;
import com.wx.spider.common.model.AppmsgParamsModel;
import com.wx.spider.common.model.Constants;
import com.wx.spider.common.pojo.mongo.WxAppmsgJson;
import com.wx.spider.common.util.HttpClientUtil;
import com.wx.spider.common.util.IdGenerateUtil;
import com.wx.spider.common.util.JsonUtils;
import com.wx.spider.common.util.StringUtil;
import com.wx.spider.mobile.config.CloudConfig;
import com.wx.spider.mobile.feign.SqlWsClient;
import com.wx.spider.mobile.repository.WxAppmsgJsonRepository;
import com.wx.spider.mobile.service.AppmsgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author:feng
 * @create:2021-04-27 15:16
 */
@Service
@Slf4j
public class AppmsgServiceImpl implements AppmsgService {

    @Autowired
    private CloudConfig cloudConfig;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    public RocketMQTemplate rocketMQTemplate;

    @Autowired
    private WxAppmsgJsonRepository wxAppmsgJsonRepository;

    @Autowired
    private SqlWsClient sqlWsClient;

    @Override
    public void getAppMsg(AppmsgParamsModel appmsgParamsModel) {

        String tarUrl = "https://mp.weixin.qq.com/mp/getappmsgext";

        //获取必须参数
        Map<String, String> headerMap = new HashMap<>();
        Map<String, String> paramMap = new HashMap<>();

        headerMap.put("Cookie", appmsgParamsModel.getCookies());
        headerMap.put("User-Agent", appmsgParamsModel.getUa());

        String referer = appmsgParamsModel.getReferer();
        Map<String, String> refererParamMap = StringUtil.getAllParam(referer.replace("==", "######"));

        String biz = refererParamMap.get("__biz").replace("######", "==");
        String mid0 = refererParamMap.get("mid");
        String idx0 = refererParamMap.get("idx");
        String sn0 = refererParamMap.get("sn");
        String phone = refererParamMap.get("phone") == null ? "12345678901" : refererParamMap.get("phone");
        String pass_ticket = refererParamMap.get("pass_ticket");

        String url = appmsgParamsModel.getUrl();
        Map<String, String> urlParamMap = StringUtil.getAllParam(url.replace("==", "######").replace("&f=json", ""));
        String key = urlParamMap.get("key");
        String appmsg_token = urlParamMap.get("appmsg_token");

        paramMap.put("is_only_read", "1");
        paramMap.put("is_temp_url", "0");
        paramMap.put("appmsg_type", "9");
        paramMap.put("__biz", biz);
        paramMap.put("key", key);
        paramMap.put("pass_ticket", pass_ticket);
        paramMap.put("appmsg_token", appmsg_token);

        //账号加入任务记录队列
        stringRedisTemplate.opsForList().rightPush(Constants.WX_BIZ_GET_APPMSG_PHONE_QUNUE, phone);

        //文章不同的标志
//        paramMap.put("mid", "2650461480");
//        paramMap.put("sn", "906b0f2f528a0ab2230b99db42182777");
//        paramMap.put("idx", "1");


        Random random = new Random();
        String qunueKey = Constants.WX_BIZ_GET_APPMSG_BIZ + biz;
        while(stringRedisTemplate.opsForList().size(qunueKey) > 0){
            String link = stringRedisTemplate.opsForList().leftPop(qunueKey);
            if(link != null){
                System.out.println("task:" + link);
                String resjson = null;

                Map<String, String> linkParamMap = StringUtil.getAllParam(link.replace("==", "######"));
                String sn = linkParamMap.get("sn");

                if(sn.equals(sn0) && appmsgParamsModel.getRes() != null){
                    resjson = appmsgParamsModel.getRes();
                }else{
                    String mid = linkParamMap.get("mid");
                    String idx = linkParamMap.get("idx");
                    paramMap.put("mid", mid);
                    paramMap.put("idx", idx);
                    paramMap.put("sn", sn);
                    //发送请求
                    int count = 0;
                    while(count ++ < 3){
                        String res = HttpClientUtil.postMap(tarUrl, headerMap, paramMap);
                        if (res != null && res.contains("read_num")){
                            resjson = res;
                            break;
                        }
                        try {
                            System.out.println("recount:"+count+",sleep " + 5 + "s!");
                            Thread.sleep(5 * 1000L);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

                if(resjson != null){
                    try {
                        Map<String, Integer> appmsgMap = JsonUtils.parseJson(resjson);

                        Integer readNum = appmsgMap.get("readNum");
                        Integer linkNum = appmsgMap.get("linkNum");
                        Integer onlookNum = appmsgMap.get("onlookNum");
                        //存mongo
                        WxAppmsgJson wxAppmsgJson = new WxAppmsgJson();
                        wxAppmsgJson.setId(IdGenerateUtil.get().nextId());
                        wxAppmsgJson.setLink(link);
                        wxAppmsgJson.setAddtime(new Date());
                        wxAppmsgJson.setReadNum(readNum);
                        wxAppmsgJson.setOnlookNum(onlookNum);
                        wxAppmsgJson.setLikeNum(linkNum);
                        wxAppmsgJson.setResjson(resjson);
                        wxAppmsgJsonRepository.save(wxAppmsgJson);

                        //存数据库
                        Boolean flag = sqlWsClient.updateWxBizNewsAppmsg(appmsgMap, biz, sn).getData();
                        if (flag){
                            System.out.println("Success update appmsg!");
                        }else{
                            log.info("1:Fail update appmsg!link:{}", link);
                        }


                        //记录当前账号完成数量
                        stringRedisTemplate.opsForList().rightPush(Constants.WX_BIZ_GET_APPMSG_ACCOUNT + phone,System.currentTimeMillis() + "");

                        //睡眠随机秒数
                        Integer min = cloudConfig.getMinSleepTimeGetAppmsg() == null ? 5 : cloudConfig.getMinSleepTimeGetAppmsg();
                        Integer max = cloudConfig.getMaxSleepTimeGetAppmsg() == null ? 10 : cloudConfig.getMaxSleepTimeGetAppmsg();
                        int r = random.nextInt(max - min) + min;
                        System.out.println("sleep " + r + "s!");
                        Thread.sleep(r * 1000L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        log.info("2:Fail update appmsg!link:{}", link);
                    }


                }else{
                    //参数失效
                    log.info("参数失效，重新入队列!link:{}", link);
                    //当前链接如此biz的队列
                    stringRedisTemplate.opsForList().rightPush(qunueKey, link);
                    //当前链接入biz任务队列
                    stringRedisTemplate.opsForList().rightPush(Constants.WX_BIZ_GET_APPMSG_QUNUE, link);
                    break;
                }
            }
        }

        //将当前账号从工作账号队列中移除
        List<String> phoneList = stringRedisTemplate.opsForList().range(Constants.WX_BIZ_GET_APPMSG_PHONE_QUNUE, 0, -1);
        if (phoneList.contains(phone))
            phoneList.remove(phone);

        stringRedisTemplate.delete(Constants.WX_BIZ_GET_APPMSG_PHONE_QUNUE);

        if(phoneList != null && phoneList.size() > 0){
            stringRedisTemplate.opsForList().rightPushAll(Constants.WX_BIZ_GET_APPMSG_PHONE_QUNUE, phoneList);
        }

        //通知空闲的模拟器去获取任务
        rocketMQTemplate.convertAndSend(MqMsgBean.PM_TO_MOBILE_SOCKET.getTopic(),"start tasks to free!");

    }
}
